package com.gee.spring.cloud.feign.flow.binding;

import org.springframework.beans.factory.BeanFactory;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * desc:
 *
 * @author gee
 * @since 2021-03-31 09:28:00
 */
public class FeignFlowProxyFactory<T> {
    private final Class<T> feignFlowInterface;
    private final Map<Method, FeignFlowMethod> methodCache = new ConcurrentHashMap<>();

    private final BeanFactory beanFactory;
    private final ThreadPoolExecutor feignFlowThreadPoolExecutor;
    public FeignFlowProxyFactory(Class<T> feignFlowInterface, BeanFactory beanFactory,
                                 ThreadPoolExecutor feignFlowThreadPoolExecutor) {
        this.feignFlowInterface = feignFlowInterface;
        this.beanFactory = beanFactory;
        this.feignFlowThreadPoolExecutor = feignFlowThreadPoolExecutor;
    }

    public Class<T> getFeignFlowInterface() {
        return feignFlowInterface;
    }

    public T newInstance(FeignFlowProxy<T> feignFlowProxy) {
        return (T) Proxy.newProxyInstance(this.feignFlowInterface.getClassLoader(), new Class[]{this.feignFlowInterface}, feignFlowProxy);
    }

    public T newInstance() {
        FeignFlowProxy<T> feignFlowProxy =
                new FeignFlowProxy(this.feignFlowInterface, methodCache, beanFactory,feignFlowThreadPoolExecutor);
        return this.newInstance(feignFlowProxy);
    }
}
